local store = require 'store'
local http = require 'resty.http'
local hc = http:new()

local delay = 1  -- in seconds
local new_timer = ngx.timer.at
local log = ngx.log
local ERR = ngx.ERR
local handler

local gmatch = function (s, pattern)
    local resultTb = {}
    local index = 0

    local i, j, k = string.find(s, pattern)
    while i do
        if k then
            resultTb[#resultTb + 1] = k
        else
            resultTb[#resultTb + 1] = string.sub(s, i, j)
        end
        i, j, k = string.find(s, pattern, j + 1)
    end

    return function ()
        index = index + 1
        return resultTb[index]
    end
end

function parse(body)
    for i in gmatch(body, "(.-)\n") do
        local id, cnt
        local c = 0
        for j in gmatch(i, "(.-),") do
            c = c + 1
            if c == 1 then
                id = j
                if id == nil then
                    break
                end
            end
            if c == 2 then
                cnt = tonumber(j)
                if cnt then
                    store:set(id, cnt)
                end

                break
            end 
        end
    end
end

function parse_new(body)
    local line_pos = 0 
    local last_pos = 0 
    local _, line_pos = string.find(body, '\n', last_pos)
    while line_pos do
        local _, id_pos = string.find(body, ',', last_pos)
        if nil == id_pos then
            break
        end 
        local id = string.sub(body, last_pos, id_pos-1)
        local _, cnt_pos = string.find(body, ',', id_pos+1)
        local cnt = tonumber(string.sub(body, id_pos+1, cnt_pos-1))

        if id and cnt then
            store:set(id, cnt)
        end 
        last_pos = line_pos+1;
        _, line_pos = string.find(body, '\n', last_pos)
    end 
end

handler = function(premature)
    local ok, code, headers, status, body = hc:request {
        url = "http://127.0.0.1/hot_item",
        timeout = 100,
        method = "GET",
        headers = { Host = "status.taobao.com" },
        fetch_size = 100*1024*1024
    }

    local date = os.date("%Y-%m-%d %H:%M:%S")
    local pos = string.find(date, " ")
    local logname = "/home/admin/cai/logs/tengine_hot_" .. string.sub(date, 1, pos - 1) .. ".log"
    local log_file = io.open(logname, "a")

    if nil ~= log_file then
        pcall(parse_new, body)

        local ms = math.random(100, 200)
        for k, v in store:listiter() do
            -- 时间|应用名|热点类目|热点ID|调用量|来源|URL
            -- YYYY-MM-dd HH:mm:ss,SSS
            local i1 = string.find(k, "&")
            local i2 = string.find(k, ":")
            local id, at, url = string.sub(k, 1, i1 - 1), string.sub(k, i1 + 1, i2 - 1), string.sub(k, i2 + 1, -1)
            --workaround for lj_str_new problen of luajit
            id = string.sub(id, 8);
            log_file:write(date .. "," .. ms .. "|" .. at .. "|" .. id .. "|" .. v .. "|tengine|" .. url .. "\n")
        end

        store:switch()
        log_file:close()
    else
        ngx.log(ngx.ERR, "create log file failed: "..logname)
    end

    ok, err = new_timer(delay, handler)
    if not ok then
        log(ERR, "failed to create timer: ", err)
        return
    end
end

local ok, err = new_timer(delay, handler)
if not ok then
    log(ERR, "failed to create timer: ", err)
    return
end
